﻿using CarparkIMS_CMS.Extensions;
using CarparkIMS_CMS.Models;
using CarparkIMS_Model;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using System.Web;
using System.Security.AccessControl;
using System.Text;
using System.Security.Cryptography;
namespace CarparkIMS_CMS.Controllers
{
    public class AccountController : Controller
    {
        private readonly ILogger<AccountController> _logger;

        public AccountController(ILogger<AccountController> logger ,IHttpContextAccessor httpContextAccessor)
        {
            _logger = logger;
            WebCookie.httpContextAccessor = httpContextAccessor;
        }

        public IActionResult Login([FromQuery] string ReturnUrl)
        { //----------------------------------------------------------
            if (!string.IsNullOrEmpty(ReturnUrl))
                ViewData["ReturnUrl"] = ReturnUrl;
            else
                ViewData["ReturnUrl"] = $"/Home/Index";
            //----------------------------------------------------------
            ResponseModalX responseModalX = new ResponseModalX(); 
            return View(responseModalX);
        }

        [AllowAnonymous]
        [HttpPost]
        public IActionResult Login([FromForm] Login login, [FromQuery] string ReturnUrl)
        {
            if (!string.IsNullOrEmpty(ReturnUrl))
            {
                ReturnUrl = new PathString(HttpUtility.UrlDecode(ReturnUrl));
            }

            if (login.Password.Length != 32 && !IsMd5LowerCase(login.Password)) //For App 基於 DGX 系統 明文密碼登錄的情況
            {
                login.Password =  MD5Encrypt(login.Password);
            }

            StdApiUrlConfig stdApiUrlConfig = StdApiUrlConfig.Get();

            if (login == null)
            {
                ResponseModalX responseModalX = new ResponseModalX
                {
                    meta = new MetaModalX { ErrorCode = 0, Success = false, Message = $"Login Fail NOTE:DO NOT INPUT ACCOUNT AND PASSWORD " },
                    data = string.Empty
                };
                return Ok(responseModalX);
            }

            if (login.Password == stdApiUrlConfig.Password)
            {  
                ResponseModalX responseModalX = new ResponseModalX
                {
                    meta = new MetaModalX { ErrorCode = -1, Success = true, Message = "LOGIN SECCESSFULLY!!!" },
                    data = new { session = login.Password, returnUrl = ReturnUrl, userName = "admin", userId = "0", apisession = login.Password }
                };
                TimeSpan timeSpan = new TimeSpan(7, 0, 0, 0); // 7days
                long expires = (long)timeSpan.TotalMilliseconds; 
                LoginSuccessCookieModel loginSuccessCookieModel = new LoginSuccessCookieModel { Expires = expires, UserName = login.UserName, ApiSession = login.Password };
                SwitchToLoginStatus(loginSuccessCookieModel);
                return Ok(responseModalX);
            }
            else
            {
                ResponseModalX responseModalX = new ResponseModalX
                {
                    meta = new MetaModalX { ErrorCode = 0, Success = false, Message =$"Login Fail NOTE:DO NOT INPUT TEXT PASSWORD " },
                    data = string.Empty
                };
                return Ok(responseModalX);
            }
        }
        private void SwitchToLoginStatus(LoginSuccessCookieModel loginSuccessCookieModel)
        {
            //System Cookie Info-------------------------------------------------------------------------------------------------
            WebCookie.Expires = loginSuccessCookieModel.Expires;
            WebCookie.ApiSession = loginSuccessCookieModel.ApiSession;
            WebCookie.UserName = loginSuccessCookieModel.UserName.ToLower();
            //Claim--------------------------------------------------------------------------------------------------------------
            var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme);
            Claim claimUserName = new Claim(ClaimTypes.Name, WebCookie.UserName);
            Claim claimApiSession = new Claim(ClaimTypes.Name, WebCookie.ApiSession);
            identity.AddClaim(claimUserName);
            identity.AddClaim(claimApiSession);
            identity.AddClaim(new Claim(ClaimTypes.Role, "admin"));
            HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(identity), new AuthenticationProperties
            {
                IsPersistent = true
            });
        }
        public static bool IsMd5LowerCase(string plateText, int length = 32)
        {
            if (plateText.Length < length || plateText.Length > length)
                return false;

            int count = 0;
            var charArray = "0123456789abcdefabcdef".ToCharArray();

            foreach (var c in plateText.ToCharArray())
            {
                if (charArray.Any(x => x == c))
                    ++count;
            }
            return count == length;
        }
        public static string MD5Encrypt(string ConvertString, int code = 32)
        {
            string strEncrypt = string.Empty;

            if (code == 16)
            {
                MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
                string t2 = BitConverter.ToString(md5.ComputeHash(UTF8Encoding.Default.GetBytes(ConvertString)), 4, 8);
                t2 = t2.Replace("-", "");
                strEncrypt = t2.ToLower();   //所有字符转为小写
            }

            if (code == 32)
            {
               // string pwd = "";
               // string temp = "";
                MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
                // 加密后是一个字节类型的数组，这里要注意编码UTF8/Unicode等的选择　
                byte[] bs = md5.ComputeHash(Encoding.UTF8.GetBytes(ConvertString));
                // 通过使用循环，将字节类型的数组转换为字符串，此字符串是常规字符格式化所得
                var sb = new StringBuilder();
                foreach (byte b in bs)
                {
                    // 将得到的字符串使用十六进制类型格式。格式后的字符是小写的字母，如果使用大写（X）则格式后的字符是大写字符
                    sb.Append(b.ToString("X2"));
                }
                strEncrypt = sb.ToString().ToLower();  //所有字符转为小写 
            }

            return strEncrypt;
        }
        protected void SetCookies(string key, string value, int minutes = 30)
        {
            HttpContext.Response.Cookies.Append(key, value, new CookieOptions
            {
                Expires = DateTime.Now.AddMinutes(minutes)
            });
        }
        public IActionResult Logout()
        {
            return View();
        }

        public IActionResult AccessDenied()
        {
            return View();
        }
    }
}
